﻿// <copyright file="IGameComponent.cs" company="SingularityShift.com">
// Copyright (c) 2010 SingularityShift.com. All rights reserved.
// </copyright>
// <author>Ben McClure</author>
// <email>ben@singularityshift.com</email>
// <date>12/2/2010</date>
// <summary>Declares the IGameComponent interface</summary>
namespace GameLib.Games
{
    using System;

    using GameLib.Games.CompositeModel;
    using GameLib.Games.Util;

    /// <summary> Interface for game component. </summary>
    /// <remarks>
    /// <para>This is the most basic type of component that can be extended to represent any part of a game.</para>
    /// <para>Both <see cref="IClient"/> and <see cref="IGameFragment"/> extend IGameComponent, on the same level as an <see cref="IComposite"/> and an <see cref="ILeaf"/>. The difference is that they do not have parents or siblings, but can have any number of children. </para>
    /// </remarks>
    /// <remarks> Ben McClure, 12/2/2010. </remarks>
    public interface IGameComponent : IComponent, ICloneable
    {
        /// <summary>
        /// Thrown when anything about a game component is changed
        /// </summary>
        event EventHandler<GameComponentChangedEventArgs> GameComponentChanged;

        /// <summary>
        /// Gets a value indicating whether this component is required in its current context.
        /// </summary>
        /// <remarks>
        /// Generally, this is a generated value which returns <see langword="true"/> if:
        /// <list type="number">
        /// <item>
        /// <description><see cref="RequiredBy"/> is not <see langword="null"/></description>
        /// </item>
        /// <item>
        /// <description><see cref="RequiredBy"/> is not empty</description>
        /// </item>
        /// </list>
        /// </remarks>
        bool Required { get; }

        /// <summary> Gets an <see cref="IGameComponentCollection"/> of components which require this component. </summary>
        /// <remarks>
        /// <para>If this component has no requirements, this value might be <see langword="null"/>.</para>
        /// <para>The component's Parent might or might not require this component. If it does, it should call the <see cref="AddRequirement"/> method of this component.</para>
        /// </remarks>
        /// <value> An <see cref="IGameComponentCollection"/> of components requiring this component, or <see langword="null"/> if it is not required by any components. </value>
        IGameComponentCollection<IGameComponent> RequiredBy { get; }

        /// <summary> Adds a requirement. </summary>
        /// <remarks>This method should make sure the component collection is created, or call the <see cref="CreateCollection"/> method to make a new one.</remarks>
        /// <param name="component"> The component which required this one. </param>
        void AddRequirement(IGameComponent component);

        /// <summary> Creates an empty collection of components. </summary>
        /// <returns> A list of. </returns>
        IGameComponentCollection<IGameComponent> CreateCollection();
    }
}
